import {
  isSupportedRecord,
  getDataType
} from '../utils.js'

class Play {
  constructor(args) {
    const {
      videoId,
      videoConfig
    } = args
    if (!videoId) {
      console.error('LveRecord: videoId为必传项')
      return
    }
    this.video = videoId
    this.videoConfig = videoConfig
    this.stream = null
    this.recordeBlobs = [] // 二进制视频文件
    this.mediaRecorder = null // 媒体对象
    this.inputData = []
  }
  setData = (data) => {
    if (!data) {
      console.error('LveRecord: 无数据')
      return false
    }
    if (getDataType(data) === 'string') {
      const type = getDataType(JSON.parse(data))
      if (type === 'array') {
        this.inputData =  JSON.parse(data)
      }
    } else if (getDataType(data) === 'array') {
      this.inputData =  data
    } else {
      console.warn('LveRecord: 非法数据类型，无法识别')
      return false
    }
    return true
  }
  /**
   * 开始播放
   **/
  startPlay = async () => {
    const isSupported = isSupportedRecord()
    if (!isSupported) return
    this.video.width = this.videoConfig.width
    this.video.height = this.videoConfig.height
    this.video.style.display = 'block'
    const can = document.createElement('canvas')
    const ctx = can.getContext('2d')
    can.width = this.videoConfig.width
    can.height = this.videoConfig.height
    ctx.fillStyle = '#fff'
    ctx.fillRect(0, 0, can.width, can.height)
    
    this.stream = can.captureStream(25);
    this.video.srcObject = this.stream; // 屏幕实时回显
    this.recordVideo(this.stream)
    for (const item of this.inputData) {
      await new Promise((resolve, reject) => {
        const flag = this.singleAnnoyPathDraw(can, item)
        if (flag) {
          resolve(flag)
        }
      })
    }
  };
  /**
   * 视频录制中
   **/
  recordVideo = (stream) => {
    this.recordeBlobs = [];
    if (!this.mediaRecorder) {
      this.mediaRecorder = new MediaRecorder(stream, {
        mimeType: 'video/webm;codecs=vp8',
      });
      this.mediaRecorder.onstop = (e) => {
        console.log('录制完成');
      };
      this.mediaRecorder.ondataavailable = (e) => {
        if (e.data && e.data.size > 0) {
          this.recordeBlobs.push(e.data);
        }
      };
      this.mediaRecorder.start(100);
    }
  }
  /**
   * 导出视频文件
   **/
  exportVideo = () => {
    if (!this.mediaRecorder) return
    this.mediaRecorder.stop();
    // stream.getTracks().forEach((track) => track.stop());
    // stream = null;
    if (this.recordeBlobs.length === 0) {
      console.warn('LveRecord: 无录制后文件')
      return
    }
    const blob = new Blob(this.recordeBlobs, { type: 'video/webm;codecs=vp8' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    a.download = '屏幕录制.webm';
    document.body.appendChild(a);
    a.click();
    setTimeout(() => {
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    }, 100);
  }
  /**
   * 单次记录绘制
   * @param can 匿名canvas
   * @param curStack 单次历史栈中的记录
   */
  singleAnnoyPathDraw = async (can, curStack) => {
    const ctx = can.getContext('2d')
    // 图片插入
    if (curStack.f === 'image') {
      await new Promise((resolve, reject) => {
        setTimeout(() => {
          this.drawImageToCanvas(can, curStack.s)
          resolve(true)
        }, curStack.t * 1000)
      })
    // 涂鸦绘制
    } else {
      for (const item of curStack) {
        await new Promise((resolve, reject) => {
          setTimeout(() => {
            if (item.s === 'start') {
              ctx.beginPath()
              ctx.moveTo(item.x, item.y)
              ctx.stroke()
            } else if (item.s === 'ing') {
              ctx.lineTo(item.x, item.y)
              ctx.stroke()
            } else {
              ctx.closePath()
            }
            resolve(true)
          }, item.t * 1000)
        })
      }
    }
  }
  /**
   * 绘制图片到canvas上(视频区)
   **/
  drawImageToCanvas = (can, imgData) => {
    const ctx = can.getContext('2d')
    const img = new Image;
    img.src = imgData;
    img.onload = () => {
      ctx.drawImage(img, 0, 0, can.width, can.height)
    }
  }
}

export default Play